import Utils from "../utils/Utils";

const {eq, assign, defaultTo, prefixName} = Utils

class UText implements UComponent {
  
  get name(): string {
    return this.options.name
  }
  
  get zIndex(): number {
    return this.options.zIndex
  }

  options: Required<UComponent.TextOpt> = {
    x: 0,
    y: 0,
    zIndex: 1,
    name: prefixName('u_text'),
    color: 'black',
    content: 'default text',
    fontSize: 14,
    fontStyle: 'serif',
    stroke: false,
    textAlign: 'start',
    textBaseline: 'alphabetic',
    direction: 'ltr',
    maxWidth: Number.MAX_SAFE_INTEGER,
    backgroundColor: 'transparent'
  }

  visible: boolean = true

  constructor(uTextOpt?: UComponent.TextOpt) {
    this.setOption(uTextOpt)
  }
  
  setOption(uTextOpt?: Partial<UComponent.TextOpt>) {
    this.options = assign(this.options, defaultTo(uTextOpt, {})) as Required<UComponent.TextOpt>
  }
  
  draw(ctx: CanvasRenderingContext2D) {
    const {x, y, color, content, fontStyle, fontSize, stroke} = this.options
    const {textBaseline, textAlign, direction, maxWidth, backgroundColor} = this.options

    ctx.save()

    ctx.font = `${fontSize}px ${fontStyle}`
    ctx.textBaseline = textBaseline
    ctx.textAlign = textAlign
    ctx.direction = direction

    const textMetrics = ctx.measureText(content)

    const {width, fontBoundingBoxAscent} = textMetrics
    ctx.fillStyle = backgroundColor

    let _width = eq(maxWidth, Number.MAX_SAFE_INTEGER) ? width : maxWidth
    ctx.fillRect(x, y - fontBoundingBoxAscent, _width, fontSize)

    if (stroke) {
      ctx.strokeStyle = color
      ctx.strokeText(content, x, y, maxWidth)
    } else {
      ctx.fillStyle = color
      ctx.fillText(content, x, y, maxWidth)
    }

    ctx.restore()
  }

}

export default UText
